home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / Main.bin / MaskedTextField.java < prev    next >
Text File  |  1998-10-22  |  8KB  |  232 lines

  1. package com.symantec.itools.awt;
  2.  
  3. import java.awt.event.KeyEvent;
  4. import java.awt.event.KeyAdapter;
  5. import java.awt.event.FocusEvent;
  6. import java.awt.event.FocusAdapter;
  7. import java.awt.datatransfer.*;
  8. import com.symantec.itools.swing.MaskEngine;
  9.  
  10. public class MaskedTextField extends java.awt.TextField {
  11.  
  12.   /* These constants are used to specify the data type information needed
  13.      to specialize input time behavior based on data type.
  14.      For now, the only such difference is between text and numeric:
  15.      In numeric fields, an empty field is initialzed to zero, and input of
  16.      a decimal point when the mask contains one and the cartet is to its left
  17.      causes the caret to move to the right of the decimal point position.
  18.   */
  19.   public static final int texttype = MaskEngine.texttype;
  20.   public static final int numbtype = MaskEngine.numbtype;
  21.   public static final int datetype = MaskEngine.datetype;
  22.   public static final int timetype = MaskEngine.timetype;
  23.  
  24.   // ctors
  25.     public MaskedTextField (                   ) { this(""         , 0              ); }
  26.     public MaskedTextField (int numberOfColumns) { this(""         , numberOfColumns); }
  27.     public MaskedTextField (String initialText ) { this(initialText, 256            ); }
  28.  
  29.     // All other constructors call this one
  30.     public MaskedTextField(String initialText, int numberOfColumns)    {
  31.       super(initialText, numberOfColumns);
  32.     }
  33.  
  34.   /**
  35.     Initialize the field
  36.   */
  37.   public synchronized void setMaskedText(String t) {
  38.     StringBuffer newData = new StringBuffer();
  39.     _firstInputPos = _maskEngine.initDisplay(t, newData);
  40.     setText(newData.toString());
  41.     if (_haveFocus && isEditable())
  42.       select(_firstInputPos, _firstInputPos + 1);
  43.     _dataComplete = false;
  44.   }
  45.  
  46.   // Returns current text with mask characters removed
  47.   public synchronized String getUnmaskedText() {
  48.     StringBuffer newData = new StringBuffer();
  49.     _dataComplete = _maskEngine.stripMask(getText(), newData);
  50.     return newData.toString();
  51.   }
  52.  
  53.   public boolean isDataComplete() {
  54.     if (!_dataComplete) {
  55.       if (!_activity)
  56.         return true;
  57.       _dataComplete = _maskEngine.stripMask(getText(), new StringBuffer());
  58.     }
  59.     return _dataComplete;
  60.   }
  61.  
  62.   /**
  63.    * This is a standard AWT method which gets called when
  64.    * this component is added to a container. Typically, it is used to
  65.    * create this component's peer.
  66.    * It has been overridden to add listener(s).
  67.    *
  68.    * @see #removeNotify
  69.    */
  70.   public synchronized void addNotify() {
  71.     if (_focusListener == null) {
  72.       _focusListener = new FocusAdapter() {
  73.         public void focusGained(FocusEvent e) { gotFocus (e); }
  74.         public void focusLost  (FocusEvent e) { lostFocus(e); }
  75.       };
  76.       addFocusListener(_focusListener);
  77.       if (isEditable()) {
  78.         _keyListener = new KeyAdapter() {
  79.           public void keyPressed (KeyEvent e) { keyPress  (e); }
  80.           public void keyTyped   (KeyEvent e) { keyType   (e); }
  81.           public void keyReleased(KeyEvent e) { keyRelease(e); }
  82.         };
  83.         addKeyListener(_keyListener);
  84.       }
  85.     }
  86.     super.addNotify();
  87.   }
  88.  
  89.   /**
  90.    * This method gets called when this component is removed from a
  91.    * container. Typically, it is used to destroy the peers of this
  92.    * component and all its subcomponents.
  93.    * It has been overridden here to remove listener(s).
  94.    *
  95.    * @see #addNotify
  96.    */
  97.   public synchronized void removeNotify() {
  98.     if (_focusListener != null) {
  99.         removeFocusListener(_focusListener);
  100.         _focusListener = null;
  101.         if (_keyListener != null)
  102.           removeKeyListener(_keyListener);
  103.         _keyListener = null;
  104.     }
  105.     super.removeNotify();
  106.   }
  107.  
  108.   protected void gotFocus(FocusEvent e) {
  109.     _haveFocus = true;
  110.     _activity = false;
  111.     if (getText().length() == 0) {
  112.       setMaskedText("");  // show the mask literals if field is empty
  113.     } else {
  114.       if (isEditable() && _lastContents.compareTo(getText()) != 0)
  115.         select(_firstInputPos, _firstInputPos + 1);
  116.       _dataComplete = false;
  117.     }
  118.   }
  119.  
  120.   protected void lostFocus(FocusEvent e) {
  121.     _haveFocus = false;
  122.     _lastContents = getText();
  123.   }
  124.  
  125.   protected void keyPress(KeyEvent e) {
  126.     _activity = true;
  127.     if (_maskEngine.isHandledKey(e) && isEditable()) {
  128.       e.consume();
  129.       if (_keyPressed) { // key must be auto-repeating
  130.         if (Character.isISOControl(e.getKeyChar()))
  131.           processKey(e);
  132.       } else
  133.         _keyPressed = true;
  134.     }
  135.   }
  136.  
  137.   protected void keyType(KeyEvent e) {
  138.     _activity = true;
  139.     if (_maskEngine.isHandledKey(e) && isEditable())
  140.       processKey(e);
  141.   }
  142.  
  143.   protected void keyRelease(KeyEvent e) {
  144.     _keyPressed = false;
  145.     _activity = true;
  146.     if (_maskEngine.isHandledKey(e) && isEditable()) {
  147.       if (Character.isISOControl(e.getKeyChar()))
  148.         processKey(e);
  149.     }
  150.   }
  151.  
  152.   protected void processKey(KeyEvent e) {
  153.     e.consume();
  154.     StringBuffer newData = new StringBuffer("");
  155.     int pos = getCaretPosition();
  156.     String data = getText();
  157.     int newpos = _maskEngine.processKey(e, pos, data, newData,
  158.                                         getSelectionStart(), getSelectionEnd());
  159.     if (newpos == -2)  // quit if filter mismatch
  160.       return;
  161.     setText(newData.toString());
  162.     if (newpos >= 0) {              // if good new caret position
  163.       select(newpos, newpos + 1);  // select this position
  164.     } else if (newpos == -1) {
  165.       java.awt.Toolkit.getDefaultToolkit().beep();
  166.       select(pos, pos);
  167.     } else {  // cursor just moved out of range
  168.       select(0,0);  // turn off selection
  169.       setCaretPosition(newpos + 1000);  // move one past last filter
  170.     }
  171.   }
  172.  
  173.   public synchronized void cut(Clipboard clipboard) {
  174.     if (!isEditable())
  175.       return;
  176.     _activity = true;
  177.     StringBuffer newData = new StringBuffer();
  178.     int selStart = getSelectionStart();
  179.     String clipboardData = _maskEngine.cut(getText(), selStart,
  180.                                            getSelectionEnd(),
  181.                                            newData);
  182.     StringSelection ss = new StringSelection(clipboardData);
  183.     clipboard.setContents(ss, ss);
  184.     setText(newData.toString());
  185.     setCaretPosition(selStart);
  186.   }
  187.  
  188.   public synchronized boolean paste(Clipboard clipboard) {
  189.     if (!isEditable())
  190.       return true;
  191.     _activity = true;
  192.     StringBuffer newData = new StringBuffer();
  193.     String data = "";
  194.     try {
  195.       data = (String)clipboard.getContents(this).getTransferData(DataFlavor.stringFlavor);
  196.     } catch (Exception e) { return false; }
  197.     int newpos = _maskEngine.paste(getText(), data, getCaretPosition(), newData,
  198.                           getSelectionStart(), getSelectionEnd());
  199.     if (newpos < 0)   // beep if paste failed
  200.       getToolkit().beep();
  201.     if (newpos == -2) // quit if filter mismatch
  202.       return false;
  203.     setText(newData.toString());
  204.     if (newpos >= 0) {              // if good new caret position
  205.       select(newpos, newpos + 1);  // select this position
  206.     } else {
  207.       select(0, 0);  // turn off selection
  208.       if (newpos != -1)  // cursor just moved out of range
  209.         setCaretPosition(newpos + 1000);  // move one past last filter
  210.     }
  211.     return true;
  212.   }
  213.  
  214.   // Property accessors
  215.   public void   setMask    (String mask) {        _maskEngine.setMask    (mask); }
  216.   public String getMask    (           ) { return _maskEngine.getMask    (    ); }
  217.   public void   setDatatype(int    type) {        _maskEngine.setDatatype(type); }
  218.   public int    getDatatype(           ) { return _maskEngine.getDatatype(    ); }
  219.  
  220.   // Variables
  221.     private FocusAdapter  _focusListener = null;
  222.     private MaskEngine    _maskEngine    = new MaskEngine();
  223.     private KeyAdapter    _keyListener   = null;
  224.     private boolean       _dataComplete  = false;   // true iff no mandatory filters are empty
  225.     private boolean       _haveFocus     = false;   // true if this component has input focus
  226.     private boolean       _activity      = false;
  227.     private boolean       _keyPressed    = false;
  228.     private String        _lastContents  = "";      // contents on last loss of focus
  229.     private int           _firstInputPos = 0;       // position of first filter
  230. }
  231.  
  232.